type ResizeListener = (element: HTMLElement) => void;

// =============================== Const ===============================
const resizeElementListeners = new Map<HTMLElement, Set<ResizeListener>>();

// 初始化时也会执行
function onResize(entities: ResizeObserverEntry[]) {
  entities.forEach((entity) => {
    const { target } = entity;
    resizeElementListeners
      .get(target as HTMLElement)
      ?.forEach((listener) => listener(target as HTMLElement));
  });
}

const ymCompResizeObserver = new ResizeObserver(onResize); //初始化项目解析该文件时就new 一次(window.resizeObserver=...)，与js模块化(import/export)无关,单例模式

export function observe(element: HTMLElement, callback: ResizeListener) {
  if (!resizeElementListeners.has(element)) {
    resizeElementListeners.set(element, new Set());
    ymCompResizeObserver.observe(element); //开始监听
  }
  resizeElementListeners.get(element)!.add(callback);
}

export function unobserve(element: HTMLElement, callback: ResizeListener) {
  if (resizeElementListeners.has(element)) {
    resizeElementListeners.get(element)!.delete(callback);
    if (!resizeElementListeners.get(element)!.size) {
      ymCompResizeObserver.unobserve(element);
      resizeElementListeners.delete(element);
    }
  }
}

//原理： ResizeObserver只实例化了一次，当在多处observe同一个element时，不能直接unobserve该element,否则所有地方该element的监听都会停止
